Imports System.IO

Friend Class TH_BikiRom_Up
    Inherits Threads.BikiThread
    Private m_sector As Integer = 0
    Friend m_end As Integer = 262143
    Friend m_packetSize As Integer = 256

    Friend m_CRC1 As UInt32 = 0
    Friend m_CRC2 As UInt32 = 0
    Friend m_CRC3 As UInt32 = 0
    Friend m_CRC4 As UInt32 = 0

    Private m_data() As Byte
    Private m_lngHandle As Integer

    Friend Sub New(ByVal SectorNo As Integer, ByVal packetSize As Integer, ByRef Array_() As Byte, ByVal lngHandle As Integer)
        m_sector = SectorNo
        m_packetSize = packetSize
        m_data = Array_
    End Sub

    Friend Overloads Function Execute( _
             ByVal backGroundWorker As System.ComponentModel.BackgroundWorker, _
             ByVal e As System.ComponentModel.DoWorkEventArgs) As Boolean
        MyBase.Execute(backGroundWorker, e)
        OnMessage("Uploading started!")

        BikiRom_SetTimeout(50)

        '' ------------- Do the actual upload
        Dim f_return As BK_return = BikiRom_Init()
        If f_return = BK_return.BK_OK Then
            'arrayDump(m_data, "c:\dump\upload.bin")
            Dim retValue As BK_return = BikiRom_UploadSectorNew(m_sector, m_data)
            '' -------------- If upload succesful then update the bikirom crc's to match
            If retValue = BK_return.BK_OK Then
                If m_CRC1 <> 0 Then SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, m_CRC1)
                If m_CRC2 <> 0 Then SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_2, m_CRC2)
                If m_CRC3 <> 0 Then SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, m_CRC3)
                If m_CRC4 <> 0 Then SetUsbVariable(Biki_USBvars.UV_BikPROG, m_CRC4)
                OnProgress(100)
                OnMessage("Uploading Complete")
            Else
                'OnMessage(Err_Decode(retValue))
            End If
        Else
            OnMessage(Err_Decode(f_return))
        End If

        BikiRom_Reset()
        close_bikirom()
    End Function
    Private Function BikiRom_UploadSector(ByVal sector As BikiAction, ByRef b_array() As Byte) As BK_return
        Dim i As Object
        Dim cmd() As Byte = Nothing
        Dim cmd1() As Byte = Nothing
        Dim ret(512) As Byte
        Dim m_cursor As Double
        Dim s_crc As Double
        Dim s_data(512) As Byte
        Dim s_error As Byte
        Dim s_length As Integer = 65535
        Dim s_init() As Byte = {0}

        If lngHandle <> 0 And sector >= BikiAction.BK_MAP1 And sector <= BikiAction.BK_ALL Then

            ' Setup the Upload and start command
            Select Case sector
                Case BikiAction.BK_MAP1
                    cmd = cv_BytesFromHex("CC3100AF0000")
                    cmd1 = cv_BytesFromHex("AF0000")
                Case BikiAction.BK_MAP2
                    cmd = cv_BytesFromHex("CC3100AF8000")
                    cmd1 = cv_BytesFromHex("AF8000")
                Case BikiAction.BK_MAP3
                    cmd = cv_BytesFromHex("CC3101AF0000")
                    cmd1 = cv_BytesFromHex("AF0000")
                Case BikiAction.BK_CFG
                    cmd = cv_BytesFromHex("CC3101AF8000")
                    cmd1 = cv_BytesFromHex("AF8000")
                Case BikiAction.BK_ALL
                    cmd = cv_BytesFromHex("CC3100AF0000")
                    cmd1 = cv_BytesFromHex("AF0000")
                    s_length = 262143
            End Select
            ' Erase Sector First

            OnMessage("Erasing.......")

            Dim f_q As BK_return = Me.BikiRom_EraseSector(sector)
            If f_q <> BK_return.BK_OK Then
                Return f_q
                GoTo close
            End If

            If Not BikiRom_ReInit() Then Return BK_return.BK_FAILED_INIT
            ' Send command
            If BikiRom_sendCmdd(cmd, ret, 3, 1) = True Then
                If ret(0) <> 170 Then
                    Return BK_return.BK_FAILED_CMD
                    GoTo close
                End If
            Else
                Return BK_return.BK_IO_ERROR_BIK
                GoTo close
            End If
            If BikiRom_sendCmdd(cmd1, ret, 3, 1) = True Then
                If ret(0) <> 170 Then
                    Return BK_return.BK_FAILED_CMD
                    OnMessage("return not correct")
                    GoTo close
                End If
            Else
                Return BK_return.BK_IO_ERROR_BIK
                GoTo close
            End If

            ' Upload Data
            s_data(0) = 223
            OnMessage("Uploading........")
            For m_cursor = 0 To s_length Step m_packetSize

                ' Copy and Calculate Crc byte
                s_crc = 0
                array_copy(b_array, m_cursor, s_data, 1, m_packetSize)
                For i = 1 To m_packetSize
                    s_crc = s_crc + CByte(s_data(i))
                Next
                s_data(m_packetSize + 1) = LOBYTE(s_crc)
reSend:
                ' Send Data packet
                If Not BikiRom_sendCmdd(s_data, ret, m_packetSize + 2, 1) Then
                    Return BK_return.BK_IO_ERROR_BIK
                    GoTo close
                Else
                    If ret(0) <> 223 Then
                        s_error = s_error + 1
                        If s_error >= 100 Then
                            Return BK_return.BK_IO_CRC_FAILED
                            GoTo close
                        End If
                        GoTo reSend
                    End If
                End If
                If bgw.CancellationPending Then
                    eventArgs.Cancel = True
                    Exit For
                End If
                ' Calculate Progress
                If (m_cursor Mod 1024) = 0 Then
                    OnProgress(((m_cursor / s_length) * 100))
                End If
            Next

            ' Send End Marker Packet
            cmd = cv_BytesFromHex("FF")
            If BikiRom_sendCmdd(cmd, ret, 1, 1) Then
                OnProgress(100)
                OnMessage("Upload Complete")
                Return BK_return.BK_OK
            Else
                OnMessage("Upload Failed...")
                Return BK_return.BK_FAILED_CMD
            End If
        Else
            Return BK_return.BK_ERROR_CATCH
        End If
close:
    End Function

    Private Function BikiRom_EraseSector(ByVal sector As BikiAction) As BK_return
        Dim cmd() As Byte
        Dim s_init() As Byte = {0}
        Dim ret(10) As Byte

        If lngHandle <> 0 And sector >= BikiAction.BK_MAP1 And sector <= BikiAction.BK_ALL Then
            BikiRom_SetTimeoutHigh(True)
            Select Case sector
                Case BikiAction.BK_MAP1
                    cmd = cv_BytesFromHex("CC3400AF0000")
                    GoTo singleCmd
                Case BikiAction.BK_MAP2
                    cmd = cv_BytesFromHex("CC3400AF8000")
                    GoTo singleCmd
                Case BikiAction.BK_MAP3
                    cmd = cv_BytesFromHex("CC3401AF0000")
                    GoTo singleCmd
                Case BikiAction.BK_CFG
                    cmd = cv_BytesFromHex("CC3401AF8000")
                    If BikiRom_sendCmdd(cmd, ret, 6, 3) = True Then
                        If ret(1) <> 255 Then
                            Return BK_return.BK_FAILED_ERASE
                            Exit Function
                        End If
                    Else
                        Return BK_return.BK_IO_ERROR_BIK
                        Exit Function
                    End If
                    BikiRom_sendCmdd(s_init, ret, 1, 1)
                    System.Threading.Thread.Sleep(20)
                    cmd = cv_BytesFromHex("CC3401AFC000")
                    If BikiRom_sendCmdd(cmd, ret, 6, 3) = True Then
                        If ret(1) <> 255 Then
                            Return BK_return.BK_FAILED_ERASE
                            Exit Function
                        End If
                    Else
                        Return BK_return.BK_IO_ERROR_BIK
                        Exit Function
                    End If
                    cmd = cv_BytesFromHex("CC3401AFD000")
                    BikiRom_sendCmdd(s_init, ret, 1, 1)
                    System.Threading.Thread.Sleep(20)

                    If BikiRom_sendCmdd(cmd, ret, 6, 3) = True Then
                        If ret(1) <> 255 Then
                            Return BK_return.BK_FAILED_ERASE
                            Exit Function
                        End If
                    Else
                        Return BK_return.BK_IO_ERROR_BIK
                        Exit Function
                    End If
                    cmd = cv_BytesFromHex("CC3401AFE000")
                    BikiRom_sendCmdd(s_init, ret, 1, 1)
                    System.Threading.Thread.Sleep(20)

                    If BikiRom_sendCmdd(cmd, ret, 6, 3) = True Then
                        If ret(1) <> 255 Then
                            Return BK_return.BK_FAILED_ERASE
                            Exit Function
                        End If
                    Else
                        Return BK_return.BK_IO_ERROR_BIK
                        Exit Function
                    End If
                Case BikiAction.BK_ALL
                    cmd = cv_BytesFromHex("CC3300")
                    GoTo singleCmd
            End Select
        End If
        BikiRom_SetTimeoutHigh(False)
        Return BK_return.BK_OK
        Exit Function
singleCmd:
        If BikiRom_sendCmdd(cmd, ret, 6, 3) = True Then
            If ret(1) <> 255 Then
                Return BK_return.BK_FAILED_ERASE
                Exit Function
            End If
        Else
            Return BK_return.BK_IO_ERROR_BIK
            Exit Function
        End If
        Return BK_return.BK_OK
        BikiRom_SetTimeoutHigh(False)
    End Function

    Private Function BikiRom_EraseSectorNew(ByVal sector As BikiAction) As BK_return
        Dim f_Frame As Comm.Comm_Frame
        m_BikiInfo.TimeOut = 8000
        Try
            If sector And BikiAction.BK_MAP1 And _
             sector And BikiAction.BK_MAP2 And _
             sector And BikiAction.BK_MAP3 And _
             sector And BikiAction.BK_CFG _
            Then
                f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3C000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASEALL)
                f_Frame.Send()
                SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, 0)
                SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_2, 0)
                SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, 0)
            Else
                If sector And BikiAction.BK_MAP1 Then
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H0, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, 0)
                End If
                If sector And BikiAction.BK_MAP2 Then
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H10000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_2, 0)
                End If
                If sector And BikiAction.BK_MAP3 Then
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H20000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, 0)
                End If
                If sector And BikiAction.BK_CFG Then
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H30000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H38000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3A000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3C000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                End If
                If sector And BikiAction.BK_ALL Then
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3C000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASEALL)
                    f_Frame.Send()
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, 0)
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_2, 0)
                    SetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, 0)
                End If
            End If
        Catch exComm As Comm_Exceptions
            OnMessage(exComm.Description)
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_BIK
        Catch exUsb As USB_exceptions
            OnMessage(exUsb.Description)
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_USB
        End Try
        m_BikiInfo.TimeOut = 500
        Return BK_return.BK_OK
    End Function

    Private Function BikiRom_UploadSectorNew(ByVal sector As BikiAction, ByRef b_array() As Byte) As BK_return
        Dim f_Frame As Comm.Comm_Frame
        Dim f_Start As ULong
        Dim f_End As ULong
        Dim f_offset As ULong = 0
        Dim i As ULong
        Dim f_PacketSize As UInt16 = m_BikiInfo.MaxTxPacket
        Dim f_Packet(f_PacketSize - 1) As Byte

        Try
            ' Do the erase section
            OnMessage("Erasing.......")
            If Me.BikiRom_EraseSectorNew(sector) <> BK_return.BK_OK Then Return BK_return.BK_FAILED_ERASE
            For l As Byte = 0 To 3
                Select Case l
                    Case 0
                        If sector And BikiAction.BK_MAP1 Then
                            f_Start = 0
                            f_End = 65535
                        Else
                            f_offset += &H10000
                            GoTo nex
                        End If
                    Case 1
                        If sector And BikiAction.BK_MAP2 Then
                            f_Start = 65536
                            f_End = 131071
                        Else
                            f_offset += &H10000
                            GoTo nex
                        End If
                    Case 2
                        If sector And BikiAction.BK_MAP3 Then
                            f_Start = 131072
                            f_End = 196607
                        Else
                            f_offset += &H10000
                            GoTo nex
                        End If
                    Case 3
                        If sector And BikiAction.BK_CFG Then
                            f_Start = 196608
                            f_End = 262143
                        Else
                            f_offset += &H10000
                            GoTo nex
                        End If
                End Select
                f_PacketSize = m_BikiInfo.MaxTxPacket
                ReDim f_Packet(f_PacketSize - 1)
                m_BikiInfo.TimeOut = 8000
                OnMessage("Uploading.......")
                For i = f_Start To f_End - f_PacketSize Step f_PacketSize
                    ' get each and every packet
                    Array.Copy(b_array, CLng(i - f_offset), f_Packet, 0, f_PacketSize)
                    If Not BlankPacket(f_Packet) Then
                        f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_FLASH_DATA, i, Comm.Comm_Frame.BikiFrameAction.WRITE, f_Packet)

                        f_Frame.Send(, , 10)
                    End If

                    OnProgress(((i) / (UBound(b_array))) * 100)
                Next

                If ((f_End - f_Start) Mod f_PacketSize) <> 0 Then
                    ' get the final and last packet here... fool :)
                    f_PacketSize = ((f_End - f_Start) Mod f_PacketSize) + 1
                    ReDim f_Packet(f_PacketSize - 1)

                    Array.Copy(b_array, CLng((f_End - f_offset) - f_PacketSize + 1), f_Packet, 0, f_PacketSize)

                    If Not BlankPacket(f_Packet) Then
                        f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_FLASH_DATA, f_End - f_PacketSize + 1, Comm.Comm_Frame.BikiFrameAction.WRITE, f_Packet)

                        f_Frame.Send(, , 10)
                    End If
                End If

nex:        Next
        Catch exComm As Comm_Exceptions
            OnMessage(exComm.Description)
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_BIK
        Catch exUsb As USB_exceptions
            OnMessage(exUsb.Description)
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_USB
        End Try
        Return BK_return.BK_OK
    End Function

    Private Function BlankPacket(ByRef Packet() As Byte) As Boolean
        For i As UInt32 = 0 To UBound(Packet)
            If Packet(i) <> &HFF Then Return False
        Next
        Return True
    End Function
End Class
